﻿namespace Sail {


    export interface ApiSet {
        action: string,
        data?: any,
        success: Function
    }

    export class ApiHelper {
        private Controller: string;
        constructor(controller: string) {
            this.Controller = controller;
        }

        public GetApi(actionName: string): string {
            return $.SailConfig.ApiRoot + this.Controller + "/" + actionName;
        };

        public get(action: string, data?: any, success?: Function) {
            if (typeof (data) == "function") {
                success = data;
                data = null;
            }
            $.get(this.GetApi(action), data, result => { success(result); });
        }

        public post(action: string, data?: any, success?: Function) {
            if (typeof (data) == "function") {
                success = data;
                data = null;
            }
            $.post(this.GetApi(action), data, result => { success(result); });
        }

        public put(action: string, data?: any, success?: any) {

            if (typeof (data) == "function") {
                success = data;
                data = null;
            }
            $.ajax({
                type: "put",
                url: this.GetApi(action),
                data: data,
                success: result => { success(result); }
            });
        }

        public delete(action: string, data?: any, success?: Function) {
            if (typeof (data) == "function") {
                success = data;
                data = null;
            }
            $.ajax({
                type: "delete",
                url: this.GetApi(action),
                data: data,
                success: result => { success(result); }
            });
        }

    }

    export interface IRazorPageSet {
        saveApi: string,
        isAutoHide: boolean,
        title: string,
    }

    export class RazorPage {
        private ApiName: string;
        private IdName: string;
        private Id: string;
        public $List: JQuery;
        public btnAdd: JQuery;
        public Page: Sail.Pagination;
        public modal: Sail.Modal;
        public $form: JQuery;
        public content: JQuery;
        public $Editor: JQuery;
        public $Viewer: JQuery;
        //public $extend: JQuery;
        public setting: IRazorPageSet;

        public static Default: RazorPage;

        constructor(title: string, api: string, idName: string, set: IRazorPageSet) {
            this.ApiName = api;
            this.IdName = idName;
            this.Id = "";
            this.Page = undefined;
            this.modal = undefined;

            this.setting = $.extend({
                saveApi: "put",
                isAutoHide: true,
                title: title
            }, set);


            this.$Editor = $("<div id=divEditor></div>");
            this.$Viewer = $("<div id=divViewer></div>");

            var content = $.SailConfig.PageContent;
            this.content = $(content);

            $("#toolbar").appendTo(this.content.find(".toolbar"));


            this.$form = $('#divDetail');
            this.$List = $("#divList");
            this.btnAdd = $("#btnAdd");

            var tool = this;

            this.content.on("click", ".btnReturn", () => {
                this.Cancel();
            });

            if (this.$form.length > 0) {
                this.$form.on("click", "#btnSave", function () {
                    tool.Save(this);
                });
                var $formBody = this.$form.find(".form-body");
                this.$Editor.html($.LoadHtml("#modalTmpl")).prependTo($formBody);
                this.$Viewer.html($.LoadHtml("#viewTmpl")).prependTo($formBody);

                this.$form.initForm();
            }



            this.$Viewer.on("click", ".btnToEdit", () => {
                this.ToEdit();
            });
            this.$Editor.on("click", ".btnToView", () => {
                this.ToView();
            });




            this.btnAdd.click(() => { this.Add(); });

            if ($.fn.tooltip) this.content.find('[data-toggle="tooltip"]').tooltip();

            //this.$extend = this.$form.find(".expandForm");

            Sail.RazorPage.Default = this;
            $("body").trigger("pageInit.after", [this]);
        }

        //设置标题
        public SetTitle(title: string) {
            var $title = this.content.find(".page-title");
            if ($title.length == 0) {
                this.content.find(".page-content").prepend("<h3 class='page-title'></h3><hr>");
                $title = this.content.find(".page-title");
            }
            $title.html(title);
            return this;
        }


        /**
         * 取消事件
         * 会触发after.Cancel事件，如需自定义请使用this.content.on("after.Cancel",function(){});
         * @returns
         */
        public Cancel() {
            this.Id = "";
            if (this.modal) this.modal.Hide();
            else {
                this.$form.hide();
                this.$List.show();
            }
            this.$form.find(".has-error").removeClass("has-error");
            this.content.trigger("after.Cancel", [this.Page, this.modal ? this.modal.modal : this.$form]);
            return this;
        }

        /**
         * 修改表单页面的标题
         * @param {type} title
         */
        public SetFormTitle(title: string) {
            this.$form.find(".portlet-title span").eq(0).html(title);
        }

        ///获取api的url
        public GetApi(name: string): string {
            return $.SailConfig.ApiRoot + this.ApiName + "/" + name;
        };

        /**
         * 返回对象的id值(根据idName)
         * @param {type} obj
         * @returns
         */
        public GetDataId(obj: Object) {
            if (obj[this.IdName] == undefined)
                console.log("获取主键值失败,可能是idName不对");
            return obj[this.IdName];
        }

        /**
         * 获取列表api的url
         * @returns
         */
        public listApi(): string {
            return this.GetApi("getlist");
        }


        /**
         * 显示详情页，隐藏列表页
         * @param {string} act
         */
        private showDetail(act: string) {
            this.$form.show().ResetForm();
            this.$List.hide();
            this.$form.find("#btnSave").show().prop("disabled", false);
            this.$Viewer.hide();
            this.$Editor.show();
            this.SetFormTitle(act + this.setting.title);
            //this.$extend.ResetForm();
            //this.Expand(false);
        }

        public displayNav(isShow: boolean) {
            var $main = this.$form.find(".mainForm");
            $main.find(".tabbable  .nav:eq(0) ").Display(isShow);
        }


        //public Expand(isShow: boolean) {
        //    var $main = this.$form.find(".mainForm");
        //    //var $expand = this.$extend;
        //    if ($expand.length > 0) {
        //        if (!isShow)
        //            $main.removeClass("col-sm-8 dashed-border-right").addClass("col-sm-12");
        //        else
        //            $main.removeClass("col-sm-12").addClass("col-sm-8 dashed-border-right");
        //    }
        //    this.$extend.Display(isShow);
        //}

        //public isExpand() {
        //    return this.$extend.is(":visible");
        //}

        public ToEdit() {
            //var isExpand = this.isExpand();
            this.showDetail("编辑");

            var data = this.$form.data("dataItem");
            this.$form.find(".btnToView").show();
            this.$Editor.ItemBinder().SetObject(data);

            this.content.trigger("after.Edit", [data, this.Page, null]);
            //if (isExpand) this.Expand(true);;
        }
        public ToView() {
            //var isExpand = this.isExpand();
            this.showDetail("查看");

            var data = this.$form.data("dataItem");
            this.$Viewer.ItemBinder().SetObject(data);
            this.$form.find("#btnSave").hide();
            this.$Editor.hide();
            this.$Viewer.show();

            this.content.trigger("after.View", [data, this.Page, null]);
         //   if (isExpand) this.Expand(true);;
        }

        /**
         * 新增事件
         * 会触发after.Add事件，如需自定义请使用this.content.on("after.Add",function(){});
         * @returns
         */
        public Add() {
            this.Id = "";
            if (this.modal) {
                this.modal.modal.ResetForm();
                this.modal.Title("新增" + this.setting.title);
                this.modal.Show();
            }
            else {
                this.showDetail("新增");
                this.displayNav(false);
                this.$form.find(".btnToView").hide();
            }
            this.content.trigger("after.Add");
            return this;
        }


        /**
         * 编辑事件
         * 最后会触发after.Edit事件，如需自定义请使用this.content.on("after.Edit",function(data,page,obj){});
         * @param {type} data 要编辑的数据对象
         * @param {type} page 分页控件
         * @param {type} obj 触发事件的jquery对象
         */
        public EditAct(data: Object, page: Pagination, obj: JQuery) {
            this.Id = this.GetDataId(data);
            this.$form.data("dataItem", data);
            if (this.modal) {
                this.modal.Title("编辑" + this.setting.title);
                this.modal.modal.ResetForm();
                this.modal.modal.ItemBinder().SetObject(data);
                this.modal.Show();
            }
            else {
                this.showDetail("编辑");
                this.displayNav(false);
                this.$Editor.ItemBinder().SetObject(data);
            }
            this.$Editor.find(".btnToView").show();
            this.content.trigger("after.Edit", [data, page, obj]);
        }

        /**
        * 查看事件 
        * 最后会触发after.View事件，如需自定义请使用this.content.on("after.View",function(data,page,obj){});
        * 暂时不提供对弹窗页面的ViewAct支持
        * @param {type} data
        * @param {type} page
        * @param {type} obj
        */
        public ViewAct(data: Object, page: Pagination, obj: JQuery) {
            this.Id = this.GetDataId(data);
            this.$form.data("dataItem", data);
            if (!this.modal) {
                this.showDetail("查看");
                this.$form.find("#btnSave").hide();
                this.$Editor.hide();
                this.$Viewer.show();
                this.displayNav(true);
                this.$Viewer.ItemBinder().SetObject(data);
            }
            this.content.trigger("after.View", [data, page, obj]);
        }

        /**
         * 保存事件
         * 保存前会触发PreSave函数，如果定义了则会在PreSave函数之中对数据进行修改
         * 保存成功会触发after.Save事件，如需自定义请使用this.content.on("after.Save",function(){});
         * @param {type} btn
         * @returns
         */
        public Save(btn: JQuery): any {
            var data = {};
            var xform = this.modal ? this.modal.modal : this.$Editor;
            if (!xform.CheckValidation()) {
                MsgBox.Error("请确认所有必填项都已填写且所有内容都已正确填写");
                return null;
            }
            data = xform.GetJson();
            data = this.PreSave(xform, data);
            if (!data) return null;
            var tool = this;
            $(btn).prop("disabled", true);
            $.ajax({
                type: "put",
                url: this.GetApi(this.setting.saveApi + "/") + this.Id,
                data: { "": JSON.stringify(data) },
                success(result:any) {
                    $(btn).prop("disabled", false);
                    MsgBox.Show(result, "保存成功", () => {
                        tool.$form.data("dataItem", result.Data);
                        tool.Id = tool.GetDataId(result.Data);
                      //  var isExpand = tool.isExpand();

                        if (tool.Page) tool.Page.Query();

                        if (tool.setting.isAutoHide) {
                            tool.Cancel();
                        }
                        //if (!tool.setting.isAutoHide || isExpand) {
                        //    tool.EditAct(result.Data, tool.Page, null);
                        //    if (isExpand) tool.Expand(isExpand);
                        //}

                        tool.content.trigger("after.Save", [result]);
                    });
                },
                error() {
                    $(btn).prop("disabled", false);
                    MsgBox.Error("提交失败,请检查网络连接");
                }
            })
            return this;
        };

        /**
         * 创建分页控件
         * @param {type} param
         */
        public CreatePage(param: Sail.IPaginationSetting) {
            var tool = this;

            param = $.extend({
                getPostKey() { return $("#toolbar").GetJson(); },
                handleName: tool.listApi()
            }, param);



            this.Page = $.Pagination(param);
            this.RegisterAct($(this.Page.settings.bodyContainer), this.Page);

            $("#toolbar .btnReset").click(() => {
                $("#toolbar").ResetForm();
                this.Page.Query(1);
            });

            return this.Page;
        }

        public RegisterAct(body: JQuery, page: any) {
            var tool = this;
            body
                .on("click", ".btnView", function () {
                    tool.ViewAct($.view(this).data, page, this);
                })
                .on("click", ".btnEdit", function () {
                    tool.EditAct($.view(this).data, page, this);
                })
                .on("click", ".btnRemove", function () {
                    tool.DeleteAct($.view(this).data, page, this);
                })
                .on("click", ".btnAct", function () {
                    tool.BtnAct($.view(this).data, page, this);
                })
                .on("click", ".btnExpand", function () {
                    tool.ViewAct($.view(this).data, page, this);
                  //  tool.Expand(true);
                });
        }



        /**
         * 删除事件
         * 最后会触发after.Delete事件，如需自定义请使用this.content.on("after.Delete",function(data,page,obj){});
         * @param {type} data 要删除的对象
         * @param {type} page 分页控件
         * @param {type} obj 触发事件的jquery对象
         */
        public DeleteAct(data: Object, page: Pagination, obj: JQuery) {
            var tool = this;
            if (!confirm("确定要删除么?")) return;
            $.Delete(tool.GetApi("delete"), { "": tool.GetDataId(data) }, (result: any) => {
                MsgBox.Show(result, "", () => {
                    if (page) page.Query();
                    tool.content.trigger("after.Delete", [data, page, obj]);
                });
            });
        }

        /**
         * 按钮操作事件
         * @param {Object} data
         * @param {Pagination} page
         * @param {JQuery} obj
         */
        public BtnAct(data: Object, page: Pagination, obj: JQuery) {
            var tool = this;
            obj = $(obj);
            var act = obj.data("act");
            if (!confirm("确定要" + obj.data("originalTitle") + "么")) return;
            $.post(tool.GetApi(act), { "": tool.GetDataId(data) }, result => {
                MsgBox.Show(result, "", () => {
                    if (page) page.Query();
                    tool.content.trigger("after.Action", [data, page, obj, act]);
                });
            });
        }
         

        /**
         * 保存前对数据进行处理
         * @param {type} form
         * @param {type} modal
         */
        public PreSave(form: JQuery, model: Object): Object {
            return model;
        }
    }
}
